﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using BusinessLogicLayer.Base;
using DALLayer.Providers;
using DataDefinition;
using Objects;
namespace BusinessLogicLayer.Manager
{
    public class ArticleManager : ManagerBase<ArticleDataProvider>
    {
        #region [Constructor]
        /// <summary>
        /// Initializes a new instance of the <see cref="ArticleManager" /> class.
        /// </summary>
        public ArticleManager() { } 
        #endregion

        #region [Manager base class implementations]
        /// <summary>
        /// Pass the data provider to the class
        /// </summary>
        protected override void InitializeDataProvider()
        {
            //Pass the specific data provider to the manager class
            base.DataProvider = new ArticleDataProvider();
        }
        
        #endregion

        #region [Public Methods]
        /// <summary>
        /// Gets all the articles
        /// </summary>
        /// <returns>article list</returns>
        public List<Article> GetArticles()
        {
            //The article details
            List<Article> articleDetails = null;
            try
            {
                //Get the article details list
                articleDetails = this.GetArticles(0, false);
            }
            catch (Exception eX)
            {
                //log error here
            }
            //The article details list to return
            return articleDetails;
        }
        /// <summary>
        /// Gets the articles by id
        /// </summary>
        /// <param name="articleId">the article id</param>
        /// <returns>article list</returns>
        public List<Article> GetArticles(int articleId)
        {
            //The article details
            List<Article> articleDetails = null;
            try
            {
                //Get the article details list
                articleDetails = this.GetArticles(articleId, true);
            }
            catch (Exception eX)
            {                
                //log error here
            }
            //The article details list to return
            return articleDetails;
        }
        /// <summary>
        /// Gets the user articles by user id
        /// </summary>
        /// <param name="userID">the user id</param>
        /// <returns>user articles list</returns>
        public List<GetUserArticle> GetUserArticle(int userID)
        { 
            //The user article details to be returned
            List<GetUserArticle> userArticleDetails = null;
            try
            {
                //Get the data set returned from the data provider
                AutoFixDataSet dataSet = base.DataProvider.GetUserArticles(userID);

                if (dataSet != null && dataSet.GetUserArticles != null && dataSet.GetUserArticles.Rows != null)
                {
                    //Set the returned filled list
                    userArticleDetails = FillUserArticleObjectsByEntities(dataSet.GetUserArticles);
                }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }
            //Return the user article details list
            return userArticleDetails;
        }
        /// <summary>
        /// Gets the article by vehicle details
        /// </summary>
        /// <param name="vehicleModelId">the vehicle model id</param>
        /// <param name="vehicleModelTypeId">the vehicle model type id</param>
        /// <param name="vehicleModelTypeYearId">the vehicle model type year id</param>
        /// <param name="articleName">the article name</param>
        /// <returns>get articles by vehicle detail list</returns>
        public List<SearchArticle> GetArticleByVehicleDetails(int vehicleModelId, int vehicleModelTypeId, int vehicleModelTypeYearId, string articleName)
        {
            //The get articles by vehicle details to be returned
            List<SearchArticle> userArticleByVehicleDetails = null;
            try
            {
                //Get the data set returned from the data provider
                AutoFixDataSet dataSet = base.DataProvider.GetArticlesByVehicleDetails(vehicleModelId, vehicleModelTypeId, vehicleModelTypeYearId, articleName);

                if (dataSet != null && dataSet.GetArticleByVehicleDetails != null && dataSet.GetArticleByVehicleDetails.Rows != null)
                {
                    //Set the returned filled list
                    userArticleByVehicleDetails = FillGetArticlesByVehicleDetailsObjectsByEntities(dataSet.GetArticleByVehicleDetails);
                }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }
            //Return the get articles by vehicle details list
            return userArticleByVehicleDetails;
        }
        /// <summary>
        /// Update or insert an article.
        /// </summary>
        /// <param name="article">article object</param>
        /// <returns>true or false</returns>
        public bool UpdateArticle(Article article)
        {
            bool success = false;
            try
            {
                //if there is an id
                if (article.ArticleID > 0)
                {
                    //Update the article
                    success = base.DataProvider.UpdateArticle(article.ArticleID, article.ArticleName, article.ArticleImageUrl, article.ArticleTypeID, article.VehicleModelID, article.UserID, article.VehicleModelTypeID, article.VehicleModelTypeYearID, article.IsPublished, article.LastUpdatedDate, article.IsActive);
                }
                else
                {
                    //Insert an article
                    success = base.DataProvider.InsertArticle(article.ArticleName, article.ArticleImageUrl, article.ArticleTypeID, article.VehicleModelID, article.UserID, article.VehicleModelTypeID, article.VehicleModelTypeYearID, article.IsPublished, article.LastUpdatedDate, article.IsActive);

                }
            }
            catch (Exception eX)
            {
                // log the error here
            }
            //returns true or false
            return success;

        }
        /// <summary>
        /// insert a article returns added record object.
        /// </summary>
        /// <param name="article">article</param>
        /// <returns>articles</returns>
        public List<Article> UpdateArticleScalar(Article article)
        {

            List<Article> articleDetails = null;
            try
            {
                //Insert an article
                int identity = base.DataProvider.InsertArticleScalar(article.ArticleName, article.ArticleImageUrl, article.ArticleTypeID, article.VehicleModelID, article.UserID, article.VehicleModelTypeID, article.VehicleModelTypeYearID, article.IsPublished, article.LastUpdatedDate, article.IsActive);
                
                AutoFixDataSet dataSet = base.DataProvider.GetArticleDetails(identity, true);
                if (dataSet != null && dataSet.Article != null && dataSet.Article.Rows != null)
                {
                    articleDetails = FillArticleObjectsByEntities(dataSet.Article);
                }
            }
            catch (Exception eX)
            {
                // log the error here
            }
            //returns articleDetails
            return articleDetails;

        }
        #endregion

        #region [Private Methods]
        /// <summary>
        /// The method that gets the list of articles or just one article
        /// </summary>
        /// <param name="articleId">The article id</param>
        /// <param name="selectById">The check to see if select by id or not</param>
        /// <returns>article list</returns>
        private List<Article> GetArticles(int articleId, bool selectById)
        {
            //The article details to be returned
            List<Article> articleDetails = null;
            try
            {
                //Get the data set returned from the data provider
               AutoFixDataSet dataSet = base.DataProvider.GetArticleDetails(articleId, selectById);
              
               if (dataSet != null && dataSet.Article != null && dataSet.Article.Rows != null)
               {
                   //Set the returned filled list
                   articleDetails = FillArticleObjectsByEntities(dataSet.Article);
               }
            }
            catch (Exception eX)
            {
                //log the error here, dont throw the exception
            }
            //Return the article details list
            return articleDetails;
            
        }
        /// <summary>
        /// Fills the get articles by vehicle details object
        /// </summary>
        /// <param name="dataTable">the data table</param>
        /// <returns>The get articles by vehicle list</returns>
        private List<SearchArticle> FillGetArticlesByVehicleDetailsObjectsByEntities(AutoFixDataSet.GetArticleByVehicleDetailsDataTable dataTable)
        {
            //The get articles by vehicle details list that contains the objects
            //Loop through the data table and create new GetArticlesByVehicleDetailsObject 
            //finally select the GetArticlesByVehicleDetailsObject and convert to list
            List<SearchArticle> getArticlesByVehicleDetails = (from gabvo in
                                                                                (from gabv in dataTable.AsEnumerable<AutoFixDataSet.GetArticleByVehicleDetailsRow>()
                                                                                 select new
                                                                                 {
                                                                                     GetArticlesByVehicleDetailsObject = new SearchArticle()
                                                                                     {
                                                                                         ArticleID = gabv.ArticleID,
                                                                                         ArticleName = gabv.ArticleName,
                                                                                         ArticleImageUrl = (!(gabv.IsArticleImageUrlNull())) ? gabv.ArticleImageUrl : ""
                                                                                     }
                                                                                 })
                                                                            select gabvo.GetArticlesByVehicleDetailsObject).ToList();
            //Return the filled get articles by vehicle details list
            return getArticlesByVehicleDetails;
        }
        /// <summary>
        /// Fills the article object
        /// </summary>
        /// <param name="dataTable">the data table</param>
        /// <returns>The article list</returns>
        private List<Article> FillArticleObjectsByEntities(AutoFixDataSet.ArticleDataTable dataTable)
        {
            //The article list that contains the objects
            //Loop through the data table and create new ArticleObject 
            //finally select the ArticleObject and convert to list
            List<Article> articleDetails = (from ao in
                                                (from a in dataTable.AsEnumerable<AutoFixDataSet.ArticleRow>()
                                                 select new
                                                 {
                                                     ArticleObject = new Article()
                                                     {
                                                         ArticleID = a.ArticleID,
                                                         ArticleName = a.ArticleName,
                                                         ArticleImageUrl = a.ArticleImageUrl,
                                                         ArticleTypeID = a.ArticleTypeID,
                                                         VehicleModelID = a.VehicleModelID,
                                                         UserID = a.UserID,
                                                         VehicleModelTypeID = a.VehicleModelTypeID,
                                                         VehicleModelTypeYearID = a.VehicleModelTypeYearID,
                                                         LastUpdatedDate = a.LastUpdatedDate,
                                                         IsPublished = a.IsPublished,
                                                         IsActive = a.IsActive
                                                     }
                                                 })
                                            select ao.ArticleObject).ToList();
            //Return the filled article details list
            return articleDetails;
        }
        /// <summary>
        /// Fills the user article object
        /// </summary>
        /// <param name="dataTable">the data table</param>
        /// <returns>The user article list</returns>
        private List<GetUserArticle> FillUserArticleObjectsByEntities(AutoFixDataSet.GetUserArticlesDataTable dataTable)
        {
            //The user article list that contains the objects
            //Loop through the data table and create new UserArticleObject 
            //finally select the UserArticleObject and convert to list
            List<GetUserArticle> userArticleDetails = (from uao in
                                                (from ua in dataTable.AsEnumerable<AutoFixDataSet.GetUserArticlesRow>()
                                                 select new
                                                 {
                                                     UserArticleObject = new GetUserArticle()
                                                     {
                                                         ArticleName = ua.ArticleName,
                                                         ArticleImageUrl = ua.ArticleImageUrl,
                                                         ArticleTypeID = ua.ArticleTypeID,
                                                         ArticleID = ua.ArticleID,
                                                         StepURL = ua.StepURL,
                                                         IsPublished = ua.IsPublished
                                                     }
                                                 })
                                                    select uao.UserArticleObject).ToList();
            //Return the filled user article details list
            return userArticleDetails;
        }
        #endregion
    }
}
